1. Introduction
The Bundle Protocol (BP) application node (BPNode) is a core Flight System (cFS) application that provides RFC-9171 BP services to embedded space flight systems by integrating BP library (BPLib) with cFS framework and processes. The Goddard Space Flight Center (GSFC) Delay/Disruption Tolerant Network (DTN) Project designed and developed BPNode as a generic flight-capable node compliant with Bundle Protocol version 7 (BPv7).
BPNode 7.0 was developed in accordance with the NPR 7150 Class B engineering requirements as defined in NASA Procedural Requirements 7123.1D and 7150.2D, respectively. It relies on a subset of cFS utilities (such as fault handling, task scheduling, data recording, etc.) to avoid duplication of code and leverage a NASA Class B/A software framework common to many human and robotic missions. This framework allows BPNode to run without modifications on various hardware and software configurations. Missions can tailor their operational environment based on available cFS configurations.
BPNode also complies with the Consultative Committee for Space Data Systems (CCSDS) standards for international interoperability and conforms with the LunaNet Interoperability Specification. BPNode enables cFS to communicate with other DTN nodes using Bundle Protocol.
1.1. Purpose and Scope
This BPNode v7.0 User Guide provides its users with general understanding of node functions. It covers node installation, configuration, and operations. The guide is intentionally generic to enable customization.
This software is available as an open source distribution, released under the Apache 2.0 license. The open-source license enables the industry adoption of BPNode. Outside of major releases, updates to the open repositories are limited to bug fixes and minor enhancements to these components.
1.2. Document Review, Approval, and Update
This guide is developed and maintained by the DTN Project at NASA Goddard Space Flight Center. The document has been reviewed and approved by the team members as listed on the signature page. After initial approval, the document will be treated as a controlled document, placed under configuration management. Changes are listed in the document [Change History] log.
1.3. Support
The development team also offers training, support, and subject matter expertise to government and industry users, and can provide custom development and integration services for flight projects. A support agreement may be required for certain engagements. To contact the team, email gsfc-dtn@nasa.onmicrosoft.com. Additional information is available on the DTN website: https://www.nasa.gov/communicating-with-missions/delay-disruption-tolerant-networking/.
1.4. Assumptions
The guide assumes that node operators are already familiar with BP and DTN, as well as with cFS Framework and how it integrates with COSMOS - the chosen telemetry and command system for interfacing with BPNode.
2. Software Overview
BPNode is a DTN node that implements BP as defined in RFC 9171. The node software runs on Linux and real-time operating systems in a context where user applications communicate directly with BPNode. BPNode expects a Publish/Subscribe pattern where user applications perform as follows:
-
publish Application Data Units (ADUs) to which BPNode subscribes
-
subscribe to expected ADUs that BPNode publishes.
The entire system is composed of several modular components grouped by function. They include the core framework, mission-specific applications, supporting libraries, and development and integration tools.
2.1. Supported Platforms
The BPNode application has been built and tested on Ubuntu 20.04.6 Long-Term Support.
2.2. cFS Framework
cFS is a generic flight software architecture framework used on NASA spacecraft and cubesats. The cFS Framework is a core subset of cFS that offers an extensive ecosystem of applications and tools. The Figure 1, “Framework Structure” figure below demonstrates the external cFS and Core Flight Executive (cFE) framework structure. BPNode interacts with these elements to receive and distribute data for DTN service:
| Operating System Abstraction Layer (OSAL) |
provides features on the operating system level, including persistent storage and mutexes. |
| Platform Support Package (PSP) |
interfaces with hardware-specific elements like memory and device I/O. |
| Software Bus |
passes the data to BPNode on the application layer. Applications use it to communicate with BPNode and to exchange telemetry, directives, and events. |
| Application |
sends and receives Application Data Units (ADUs) to/from BPNode via the framework software bus. |
| Performance Services |
interacts with cFE Performance Log to provide logging functionality for BPNode by sending entries through the framework. |
| Event Logging |
interacts with cFE Event Services (EVS) to collect events generated by BPNode and distribute them via Telemetry Distribution. |
| Time Services |
interacts with cFE TIME to provide BPNode with time (host time, clock state, etc.) to calculate and maintain the time within the node. |
| Command Source |
interacts with cFS Command Ingest (CI) or Stored Command (SC) to provide directives to BPNode, such as stored commands or commands received from an external source for BPNode execution. |
| Telemetry Distribution |
interactions with cFS Telemetry Output (TO) to collect telemetry from BPNode and send it to external entities. |
| Table Services |
interacts with cFE Table Services to provide a mechanism for table updates which are used by BPNode for configuration purposes. |
| See Chapter 6, Directives, Telemetry, Tables, and Events for the list of BPNode directives, tables, and telemetry. |
2.3. BPNode and BPLib
BPNode and BPLib are complementary components that run on top of the framework:
| BPLib |
serves as the core implementation library that provides BP functionality: https://github.com/nasa/bplib |
| BPNode |
integrates this library into the cFS framework and implements the BP node behavior: https://github.com/nasa/bp |
Together they provide a shared library and support BP and related functions.
BPNode contains the following subsystems, modules, and components:
| Application Agent (AA) |
provides application and administrative services associated with monitoring and control, such as status monitoring or configuration control:
|
| BP Agent (BPA) |
executes BP-related activities and functions:
|
| Core Infrastructure (CI) |
functions as a common utility across modules for low-level functions and processing, such as memory, time, and events:
|
| Convergence Layer Adapters (CLAs) |
interfaces with external Convergence Layers (CLs) such as UDP to send and receive bundles on behalf of the BPA |
| The following features only contain skeleton code in build 7.0 and are slated for future implementation: |
-
Administrative Record Processor
-
Custody Transfer
-
Policy Database
2.4. Dependencies
For both BPNode and BPLib, the following dependencies are required:
| CMake (build system) |
version 3.22.1 used during testing |
| pkg-config |
version 0.29.1 used during testing |
| Gnu Compiler Collection toolchain |
version 9.4.0 used during testing |
| sqlite3 |
version 3.31.1 used during testing |
On Ubuntu 20.04.6, install the necessary packages with:
sudo apt-get install cmake pkg-config build-essential libsqlite3-dev
2.5. QCBOR
BPLib relies on CBOR to handle the serialization and deserialization of data structures transmitted over the protocol. BPLib uses version 1.5.1 of QCBOR for CBOR data encoding and decoding.
Follow these steps to install QCBOR:
-
Clone the QCBOR repository:
cd ~/ # Or any directory for installing QCBOR git clone https://github.com/laurencelundblade/QCBOR.git -
Navigate to the QCBOR repository:
cd QCBOR -
Select the correct version:
git checkout v1.5.1 -
Build and install the library:
sudo make uninstall # Remove any previous installation cmake -DBUILD_SHARED_LIBS=ON -S . -B build cmake --build build sudo make install
3. Installation
3.1. Building BPNode and BPLib within cFS
3.1.1. Clone Repositories
Clone the cFS repository to the local system:
git clone https://github.com/nasa/cFS.git
Follow the instructions in the cFS README to initialize the sample cFS deployment: https://github.com/nasa/cfs?tab=readme-ov-file#build-and-run
cFS relies heavily on Git submodules, so to avoid errors during when updating code, they must be kept updated by running git submodule update --init.
|
Clone the BPNode and BPLib repos as submodules in the cFS bundle.
cd cFS/apps/
git submodule add https://github.com/nasa/bp.git bpnode
cd ../../libs/
git submodule add https://github.com/nasa/bplib.git
3.1.2. Add BPNode and BPLib to cFS
To add BPNode and BPLib to the cFS build system, modify sample_defs/targets.cmake to include them in the MISSION_GLOBAL_APPLIST variable.
LIST(APPEND MISSION_GLOBAL_APPLIST bplib bpnode)
BPNode has a PSP module for UDP socket interfacing called udpsock_intf that also needs to be added to the build system. Add the following to sample_defs/mission_build_custom.cmake.
set(MISSION_MODULE_SEARCH_PATH
"apps" # general purpose $[top}/apps directory
"libs" # general purpose $[top}/libs directory
"psp/fsw/modules" # modules for optional platform abstraction, associated with PSP
"cfe/modules" # modules for optional core functions, associated with CFE
"apps/bpnode/psp_mod" # Custom PSP modules for BPNode, including udpsock_intf
)
To ensure that BPNode and BPLib are loaded automatically upon cFE startup, add them to sample_defs/cpu1_cfe_es_startup.scr.
CFE_LIB, bplib, BPLib_PrintVersion, BP_LIB, 0, 0, 0x0, 0;
CFE_APP, bpnode, BPNode_AppMain, BPNODE, 55, 16384, 0x0, 0;
To add BPNode wakeup messages at 10Hz and telemetry requests at 0.25Hz, the following sch_lab_table.c file will be needed.
#include "bpnode_msgids.h"
SCH_LAB_ScheduleTable_t SCH_LAB_ScheduleTable = {
.TickRate = 10,
.Config = {
{CFE_SB_MSGID_WRAP_VALUE(CFE_ES_SEND_HK_MID), 40, 0},
{CFE_SB_MSGID_WRAP_VALUE(CFE_EVS_SEND_HK_MID), 40, 0},
{CFE_SB_MSGID_WRAP_VALUE(CFE_TIME_SEND_HK_MID), 40, 0},
{CFE_SB_MSGID_WRAP_VALUE(CFE_SB_SEND_HK_MID), 40, 0},
{CFE_SB_MSGID_WRAP_VALUE(CFE_TBL_SEND_HK_MID), 40, 0},
{CFE_SB_MSGID_WRAP_VALUE(CI_LAB_SEND_HK_MID), 40, 0},
{CFE_SB_MSGID_WRAP_VALUE(TO_LAB_SEND_HK_MID), 40, 0},
#ifdef HAVE_SAMPLE_APP
{CFE_SB_MSGID_WRAP_VALUE(SAMPLE_APP_SEND_HK_MID), 40, 0},
#endif
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_CMD_MID), 40, 40}, /* BPNODE_SEND_NODE_MIB_CONFIG_HK_CC */
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_CMD_MID), 40, 41}, /* BPNODE_SEND_SOURCE_MIB_CONFIG_HK_CC */
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_CMD_MID), 40, 42}, /* BPNODE_SEND_NODE_MIB_COUNTERS_HK_CC */
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_CMD_MID), 40, 43}, /* BPNODE_SEND_SOURCE_MIB_COUNTERS_HK_CC */
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_CMD_MID), 40, 44}, /* BPNODE_SEND_STORAGE_HK_CC */
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_CMD_MID), 40, 45}, /* BPNODE_SEND_CHANNEL_CONTACT_STAT_HK_CC */
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_CMD_MID), 40, 46}, /* BPNODE_SEND_NODE_MIB_REPORTS_HK_CC */
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_WAKEUP_MID), 1, 0},
}};
The telemetry request rate can be customized entirely to a project’s needs.
The wakeup rate is recommended to be set to 10Hz and should not be set to slower than 1Hz.
See BPNODE_MAX_EXP_WAKEUP_RATE in bpnode/config/default_bpnode_platform_cfg.h for more details.
|
To ensure BPNode telemetry packets are egressed by to_lab, the following configurations are needed in the to_lab_sub.c file:
#include "bpnode_msgids.h"
TO_LAB_Subs_t TO_LAB_Subs = {.Subs = {/* CFS App Subscriptions */
{CFE_SB_MSGID_WRAP_VALUE(TO_LAB_HK_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(TO_LAB_DATA_TYPES_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(CI_LAB_HK_TLM_MID), {0, 0}, 4},
#ifdef HAVE_SAMPLE_APP
{CFE_SB_MSGID_WRAP_VALUE(SAMPLE_APP_HK_TLM_MID), {0, 0}, 4},
#endif
/* cFE Core subscriptions */
{CFE_SB_MSGID_WRAP_VALUE(CFE_ES_HK_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(CFE_EVS_HK_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(CFE_SB_HK_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(CFE_TBL_HK_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(CFE_TIME_HK_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(CFE_TIME_DIAG_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(CFE_SB_STATS_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(CFE_TBL_REG_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(CFE_EVS_LONG_EVENT_MSG_MID), {0, 0}, 32},
{CFE_SB_MSGID_WRAP_VALUE(CFE_ES_APP_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(CFE_ES_MEMSTATS_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_NODE_MIB_CONFIG_HK_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_SOURCE_MIB_CONFIG_HK_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_NODE_MIB_COUNTERS_HK_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_NODE_MIB_REPORTS_HK_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_SOURCE_MIB_COUNTERS_HK_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_STORAGE_HK_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_CHANNEL_CONTACT_STAT_HK_TLM_MID), {0, 0}, 4},
{CFE_SB_MSGID_WRAP_VALUE(BPNODE_ADU_OUT_SEND_TO_MID), {0, 0}, 4},
{CFE_SB_MSGID_RESERVED, {0, 0}, 0}}};
3.1.3. Building and Deploying the DTN cFS
This method is ideal for simulation, unit testing, and general development work on a local Linux machine.
Use the following commands from the top-level cFS directory:
make distclean
make SIMULATION=native prep
make
make install
cd build/exe/cpu1/
./core-cpu1
This compiles and launches the cpu1 target in a native environment.
3.1.4. Run Unit Tests and Generate Coverage
Testing is a key part of validating the DTN cFS system. The sequence below starts by cleaning and configuring the native build environment to include unit test support, followed by compilation, testing, and coverage reporting.
make distclean
make SIMULATION=native ENABLE_UNIT_TESTS=true prep
make
make test
make lcov
The resulting report can be used to assess code coverage and identify gaps in test validation.
Always run make distclean before switching targets or simulation environments to avoid build conflicts.
For advanced build configurations or debugging, consult the Makefiles and scripts included in the repository.
|
3.1.5. Troubleshooting
This section addresses common issues that may arise when working with the DTN cFS bundle.
- Missing files or directories after cloning
-
Run
git submodule update --initto ensure all nested submodules are pulled. - Unit tests not executing
-
Make sure to include
ENABLE_UNIT_TESTS=truein themake prepstep.
3.2. Standalone BPLib Build (bpcat)
BPLib can be built as a standalone executable called bpcat, suitable for a ground relay node or as a demo of bplib’s features without the full CS architecture.
This standalone build still depends on the OSAL library.
Note that bpcat does not implement the full suite of BPNode features, since the node relies on cFS for directive handling, telemetry routing, table updates, etc.
|
Build/run instructions for bpcat:
-
Clone the repositories
cd <chosen working directory> export BPLIB_HOME="$(pwd)" # Set working directory git clone https://github.com/nasa/bplib "${BPLIB_HOME}"/bplib git clone https://github.com/nasa/osal "${BPLIB_HOME}"/bplib/osal
-
Configure the build environment
# Choose a build configuration - Debug or Release export MATRIX_BUILD_TYPE=Debug # Indicate where the OSAL build files are export NasaOsal_DIR="${BPLIB_HOME}/bplib/osal-staging/usr/local/lib/cmake" # Define bplib build directory export BPLIB_BUILD="${BPLIB_HOME}/bplib/bplib-build-matrix-${MATRIX_BUILD_TYPE}-POSIX"
-
Build BPLib with OSAL
cd $BPLIB_HOME/bplib/osal cmake -DCMAKE_INSTALL_PREFIX=/usr/local \ -DOSAL_SYSTEM_BSPTYPE=generic-linux \ -DCMAKE_BUILD_TYPE="${MATRIX_BUILD_TYPE}" \ -DOSAL_OMIT_DEPRECATED=TRUE \ -DENABLE_UNIT_TESTS=TRUE \ -DOSAL_CONFIG_DEBUG_PERMISSIVE_MODE=ON \ -B ../osal-build cd ../osal-build make DESTDIR=../osal-staging install cd .. cmake -DCMAKE_VERBOSE_MAKEFILE=ON \ -DCMAKE_BUILD_TYPE="${MATRIX_BUILD_TYPE}" \ -DBPLIB_OS_LAYER=OSAL \ -DCMAKE_PREFIX_PATH=/usr/local/lib/cmake \ -B "${BPLIB_BUILD}" cd $BPLIB_BUILD make all
-
Test and execute
-
To run the bplib unit tests:
cd $BPLIB_BUILD ctest --output-on-failure 2>&1 | tee ctest.log -
To run bpcat as a standalone:
cd $BPLIB_BUILD cd app ./bpcat
-
In the default bpcat configurations, a single contact is started that listens on 0.0.0.0:4501 and forwards bundles with the EID ipn:200.64 to 127.0.0.1:4551. To change these configurations, modify the ContactsTbl in bplib/app/src/bpcat_nc.c and rebuild bplib.
4. Configuration
4.1. Startup Configuration
On startup, the BPNode main task will initialize itself, the BPLib library data, and any child tasks.
On first initialization, the node creates a SQLite database named bplib-storage.db in the same directory as the executable (typically build/exe/cpu1/) along with temporary files associated with it.
On subsequent initializations BPLib reads from it and reports the total number of bundles stored (see the Node MIB Reports telemetry packet as described in Chapter 6, Directives, Telemetry, Tables, and Events).
The node’s Endpoint Identifier (EID) is established during initialization by reading from the node MIB configuration table. This table contains an "instance EID" field that provides the base EID value used as the node’s primary identity. Channels use this EID for bundles originating on local applications, modifying the service number to match the corresponding value from the channel configuration table.
| See Chapter 6, Directives, Telemetry, Tables, and Events for more information. |
The counts of tasks are determined by the following BPNode or BPLib macros:
| BPNODE_NUM_GEN_WRKR_TASKS |
Generic Worker |
| BPLIB_MAX_NUM_CHANNELS |
ADU In/Out |
| BPLIB_MAX_NUM_CONTACTS |
CLA In/Out |
4.1.1. ADU Channels
ADU tasks are implemented via virtual communication pathways for application data called channels.
Each channel has a unique ID from 0 to BPLIB_MAX_NUM_CHANNELS - 1.
All channels default to REMOVED state at initialization unless their configuration in the channel configuration table has loadAutomatically set to true, in which case they should initialize as STARTED.
Channel ID indexes into:
-
The ADU proxy table
-
This table has any cFS-specific channel information, including which message IDs a channel should subscribe to
-
-
The channel configuration table
-
This table has general channel configurations, including the service number to assign to the channel, and how to configure new bundles created from this channel’s ADUs
-
-
The channel status array in the channel/contact status telemetry packet
| See Chapter 6, Directives, Telemetry, Tables, and Events for more information on BPNode tables. |
4.1.2. CLA Contacts
CLA tasks are implemented via network interface connections called contacts:
Each contact has a unique ID from 0 to BPLIB_MAX_NUM_CONTACTS - 1.
All contacts default to TORNDOWN state at initialization.
Contact ID indexes into:
-
The contact configuration table
-
This table has information including which destination EID(s) to associate with this contact and the needed IP information to set up a UDP contact
-
-
The contact status array in the channel/contact status telemetry packet
5. Running the Node
Main configurations that drive node performance:
| Rate limits |
see the channel and contact configuration tables (defaults located at |
| Task priorities |
see |
| Memory pool size |
see BPNODE_MEM_POOL_LEN in |
| Number of tasks in the system |
based on BPLIB_MAX_NUM_CONTACTS, BPLIB_MAX_NUM_CHANNELS, and BPNODE_NUM_GEN_WRKR_TASKS in |
| The maximum bundle bytes allowed in the storage database |
based on BPLIB_MAX_STORED_BUNDLE_BYTES in |
| The batch size of bundles |
|
Note that configurations can affect each other. The storage bundle byte limit and the memory pool size should be at least as large as the maximum bundle size times the relevant load batch sizes into or out of storage. Otherwise error event messages will start to be regularly issued when either the storage limit or the memory limit is reached.
Configurations that affect how bundles move between nodes and how bundles are created/processed are primarily found in the ADU proxy, channel configuration, and contact configuration tables. Multiple BPNode instances can be deployed in a network as source, relay, or destination nodes, as shown in Figure 2, “BPNode deployment roles” below:
To deploy multiple BPNode instances, follow the standard cFS instructions for deploying multiple CPU instances (see here) and modify the BPNode tables for each CPU instance accordingly.
5.1. Managing Channel Applications
BPNode manages channel applications by separating configuration from activation, allowing for complete lifecycle control from setup through teardown. When an application needs to be integrated into the network, it must first be added to make its configuration available, then explicitly started to begin data flow. Applications can later be stopped to halt data processing or completely removed, which flushes any remaining data from both the egress queue and the cFE software bus pipe. These application lifecycle operations are controlled through the following directives:
add-application-
this directive loads an application’s configuration by reading settings from both the ADU proxy table and channel configuration table using the specified channel ID. However, this step only makes the configuration available - no actual data processing begins until the application is started.
start-application-
this directive activates the configured application by enabling its ADU tasks to begin processing data flow. In the cFS environment, this activation involves subscribing to the relevant ADU message IDs and establishing the connection to post delivered bundle payloads to SB.
stop-application-
this directive stops the flow of ADUs in and out of the specified channel.
remove-application-
this directive flushes the egress queue of the specified channel and store any bundles found in there. It will also flush the cFE SB pipe of any new ADUs.
| See Chapter 6, Directives, Telemetry, Tables, and Events for the list of BPNode directives. |
Once active, applications participate in BP communication through two primary data flows:
| ADU In |
this task handles data originating from local applications by converting received cFS packets into bundle payloads, applying the settings specified in the channel configuration table to create properly formatted bundles for network transmission. |
| ADU Out |
this task handles inbound data bundles arriving from the network that are destined for local applications. When a bundle’s destination EID matches an application running on the current node, the bundle is routed to the appropriate task, which extracts the payload data and posts it to the cFS SB where the target application can receive it. |
This architecture allows BPNode to serve as a bridge between local cFS applications and the broader BP network, handling the translation between application-specific data formats and standardized bundle protocols.
5.2. Managing Contacts
BPNode manages network connections through contacts using a comprehensive lifecycle process similar to application management, allowing for complete control from initial setup through final teardown. Contacts represent network connections to other BP nodes and must be configured before they can actively participate in bundle routing. Like applications, contacts can be stopped to halt bundle traffic or completely torn down, which flushes any remaining bundles from the egress queue into storage. These contact lifecycle operations are controlled through the following directives:
contact-setup-
this directive establishes a contact’s network configuration by reading settings from the contact configuration table using the specified contact ID. This step creates the underlying CL connection infrastructure but leaves it in a dormant state with no bundle traffic flows until the contact is explicitly started.
contact-start-
this directive activates the configured contact by enabling its CLA tasks to begin processing bundle traffic. Once started, the contact can participate in both receiving bundles from and transmitting bundles to other nodes in the BP network.
contact-stop-
this directive stops the flow of bundles in and out of the specified contact.
contact-teardown-
this directive flushes the egress queue of the specified contact and stores any bundles found in there.
| See Chapter 6, Directives, Telemetry, Tables, and Events for the list of BPNode directives. |
Active contacts handle BP communication through two distinct pathways:
| CLA In |
this task receives encoded bundles from incoming network traffic, decodes the CBOR formatting, and deserialize the data into a readable bundle format. Each received bundle undergoes validation to ensure data integrity. Bundles that fail validation are immediately discarded to prevent corrupt data from entering the system. |
| CLA Out |
this tasks manages the outgoing traffic by routing bundles destined for remote nodes based on their destination EIDs. When a bundle’s destination corresponds to a destination EID in the started contact, it is forwarded to the appropriate task, which encodes the bundle using CBOR formatting and transmits it to the next node in the network routing path. |
This contact management system enables BPNode to maintain reliable connections with multiple network peers while ensuring data integrity through validation and proper encoding protocols.
5.3. Bundle Storage Management
When BPNode receives a bundle that cannot be immediately processed—either because its destination EID does not match any active local applications (channels) or available network connections (contacts), the system provides persistent storage to ensure reliable message delivery even across system restarts.
Such bundles are written to the SQLite database bplib-storage.db, which provides persistent storage that survives node restarts, ensuring that bundles waiting for delivery or forwarding opportunities are not lost during system maintenance or unexpected shutdowns.
The main task continuously monitors stored bundles to manage their lifecycle effectively. It regularly checks each bundle’s creation timestamp against its specified lifetime to identify expired bundles, which are automatically discarded to prevent indefinite storage of undeliverable messages. Simultaneously, the system monitors for new routing opportunities by checking whether previously unroutable bundles can now be forwarded to newly available contacts or delivered to recently started local applications. When such opportunities arise, bundles are moved from storage to the appropriate egress queue and removed from the database.
The system provides telemetry reporting on storage utilization through the storage telemetry packet, which includes both the total size of the bplib-storage.db file and the actual space consumed by stored bundles.
The bundle storage size is typically smaller than the total database file size due to SQLite’s internal database management overhead.
Storage capacity is controlled by the BPLIB_MAX_STORED_BUNDLE_BYTES macro, which sets limits based on the actual byte size of bundle content rather than total database file size.
6. Directives, Telemetry, Tables, and Events
For the list and descriptions of BPNode directives, telemetry, tables, and events, consult the Monitor & Control Interface Control Document (M&C ICD) in the BPNode repository.
7. Known Issues
-
The
maxBundlePayloadSizeconfiguration in the channel configuration table conflicts with a similar configuration in the MIB node configuration table. Currently the value in the channel configuration table is used, but eventually the one in the MIB configuration will be used. -
If the general rate of ingressing data is greater than the general rate of egressing data, memory will start to run out and ingressing bundles will start to be dropped.
-
If bundles start to expire from storage at the same time as they start to be egressed from storage, the
BUNDLE_COUNT_LIFETIME_EXPIREDtelemetry counter might erroneously count bundles that have been egressed as expired. -
Large volumes of bundles in storage result in a general system slowdown and occasional spikes in egress rates beyond what the rate limit has been configured to allow.
-
Rate limits where the bits per wakeup is set to a value smaller than the expected bundle size will result in unusual behavior.
-
Storage database sizes larger than 4GB result in unexpected errors
-
Expiration of bundles in storage does not work when bundles have an age block but no valid creation timestamp.
For a full list of issues, see the BPNode 7.0 Version Description Document. These issues are all slated for fixing in build 7.1.
8. DTN Tools Suite
Tools Suite is a toolkit that allows for:
-
confirming whether bundles created by the implementation adhere to specifications such as RFC 9171, ensuring protocol compliance at a fundamental level
-
rigorous testing of how the implementation handles invalid or off-nominal bundles
-
verifying implementation’s resistance to corrupted data
The toolkit provides comprehensive end-to-end tests within a single script for a consistent methodology for creating bundle content, covering the entire process from bundle creation through transmission to a DTN node, reception from a DTN node, and verification of received bundles.
It includes support for extension blocks like Custody Transfer Extension Block (CTEB) and Compressed Reporting Extension Block (CREB) as well as CBOR-encoded and decoded formats.
The suite contains two tools: DTNGEN and DTNCLA.
8.1. DTNGEN
DTNGEN is a Python library that enables the creation and interpretation of DTN bundles for compliance verification as well as error handling and interoperability testing between different DTN implementations. It can create both standards-compliant bundles and deliberately invalid bundles with incorrect data or block ordering.
The tool provides bundle manipulation capabilities through dedicated classes for primary blocks and canonical block types. It can generate:
-
individual bundles with customizable components (primary, payload, and extension blocks)
-
sets of bundles using:
-
script-based loops
-
specialized Bundle Set Generation feature, which allows for controlled variations in creation timestamps and payload sizes.
-
DTNGEN offers flexible data format support, allowing bundles to be read from and written to both binary and JSON formats:
{
"block_class": "PrimaryBlock",
"version": 8,
"control_flags": 4,
"crc_type": 1,
"dest_eid": {
"type": "EID",
"value": {
"uri": 2,
"ssp": {
"node_num": 103,
"service_num": 1
}
}
},
"src_eid": {
"type": "EID",
"value": {
"uri": 2,
"ssp": {
"node_num": 101,
"service_num": 1
}
}
},
"rpt_eid": {
"type": "EID",
"value": {
"uri": 2,
"ssp": {
"node_num": 100,
"service_num": 1
}
}
},
"creation_timestamp": {
"type": "CreationTimestamp",
"value": {
"time": 755533883904,
"sequence": 0
}
},
"lifetime": 3600000,
"crc": {
"type": "hexbytes",
"value": "af7c"
}
}
8.2. DTNCLA
DTNCLA is a unified Python library that implements CLAs needed for DTN testing. It provides a consistent interface for communicating with DTN nodes, regardless of the underlying convergence layer protocol.
The library follows a modular design where most functionality is shared across different CLAs, promoting code reuse and consistent behavior. Only the network read/write functions are specialized, with implementations tailored to the specific requirements of each convergence layer protocol.
8.3. Dependencies
The suite requires the following dependencies:
-
Python v3.8 or higher
-
cbor2 v5.6.2 or higher
-
crccheck v1.3.0 or higher
8.4. Tools Suite Installation
Each DTN Tools Suite release provides a complete package containing a built Python wheel file (.whl) for easy installation, source code, release notes, and documentation in HTML and PDF formats that covers all classes, variables, and usage examples that can be copied directly into test scripts.
To install for command line usage:
pip install dtntools-X.X.X-py3-none-any.whl
The source code is organized into four main folders:
| dtntools |
Contains the Python source code for DTNGEN and DTNCLA |
| docs |
Houses all HTML documentation |
| tests |
Contains scripts for testing DTN Tools, including unit tests and tests against existing DTN implementations |
| examples |
Includes demonstration scripts for DTN Node testing:
|
8.5. COSMOS Integration
The DTN Tools Suite seamlessly integrates with OpenC3 COSMOS version 5.12 and later, which supports native Python package installation. DTN Tools packages can be installed directly through the COSMOS Administrator Console, with required dependencies (cbor2 and crccheck) being automatically resolved and installed during the process.
When configuring test environments, any host ports or folders accessed by the DTN test scripts must be explicitly defined in the COSMOS compose.yaml file to ensure proper container communication. The integration enables calling DTN Tools functions directly from COSMOS script-runner, facilitating their incorporation into scripts and procedures.
| Within the COSMOS environment, some methods differ from standard Python constructs, e.g.: COSMOS uses "ask" rather than "input" for user prompts. |
Appendix A: COSMOS Interface
COSMOS is a suite of software application for integration, testing, and operations of embedded systems that can range from power supplies to satellite constellations. BPNode has been tested against OpenC3 COSMOS versions 5.17.1 and 6.3.0. All files needed to run BPNode against COSMOS are provided in the bpnode/openc3-cosmos-dtnfsw directory.
To run COSMOS with the openc3-cosmos-dtnfsw plugin, first make the following modifications to COSMOS’s compose.yaml file:
-
If you are running to_lab, add "1235:1235/udp" to the ports list under the openc3-operator section
openc3-operator:
ports:
- "1235:1235/udp"
-
If you are using one or more UDP configurations for the CLA tasks and wish to use the test tools in COSMOS to receive bundles, the CLA out port(s) need to be listed in the ports list under the openc3-cosmos-script-runner-api section For example, if you are setting the CLA Out port for contact 0 to 4551 (as in the default configurations), your compose.yaml changes should look like this:
openc3-cosmos-script-runner-api:
ports:
- "4551:4551/udp"
To build the openc3-dtnfsw-plugin, run the following command from within the bpnode/cosmos directory:
<Path to COSMOS installation>/openc3.sh cli rake build VERSION=7.0.0
COSMOS has a comprehensive user’s guide with a dedicated section for cFS integration, maintained by the OpenC3 team, so further information about the installation and operation of COSMOS is outside the scope of this document.
Appendix B: Host Assumptions
BPNode operates under the following host assumptions:
- ADU Proxy
| DTN.A.00080 |
Host provides a mechanism for the DTN Node to exchange ADUs with local client applications. |
| DTN.A.00090 |
The mechanism by which ADUs are exchanged between the DTN Node and its client applications is reliable. |
- Directive Proxy
| DTN.A.02120 |
Host provides a command ingest application that accepts and sends CCSDS telecommand packets in order. |
| DTN.A.02220 |
The host will authenticate the source of all directives. |
- Event Management
| DTN.A.00020 |
Host provides event services. |
| DTN.A.00030 |
Host event services provide the capability to filter events by event ID. |
| DTN.A.00040 |
Host event services provide the capability to filter events by event type: critical, error, info, and debug. |
| DTN.A.00050 |
Host event services include in all event messages the time at which the event occurred. |
| DTN.A.00060 |
Host event services will send event messages in the form of CCSDS Space Packets. |
- Event Proxy
| DTN.A.00020 |
Host provides event services. |
| DTN.A.00030 |
Host event services provide the capability to filter events by event ID. |
| DTN.A.00040 |
Host event services provide the capability to filter events by event type: critical, error, info, and debug. |
| DTN.A.00050 |
Host event services include in all event messages the time at which the event occurred. |
| DTN.A.00060 |
Host event services shall send event messages in in a form specified by the flight software framework. |
- TABLE
| DTN.A.02030 |
Host Table Services supports initialization of the DTN Node configuration. |
| DTN.A.02031 |
Host Table Services performs table updates synchronously with the DTN Node application that owns the table to ensure data integrity and table activation atomicity. |
| DTN.A.02032 |
Host Table Services supports common viewing of DTN Node application configuration and policy data structures. |
| DTN.A.02200 |
The host will load configuration updates via table. |
| DTN.A.02210 |
The host will dump DTN Node configuration from tables. |
- TIME and Time Management
| DTN.A.00000 |
Host provides a monotonic clock that gives a count of ticks since the most recent power-on reset. |
| DTN.A.00005 |
Host monotonic time will not rollover during the duration of the mission. |
| DTN.A.00010 |
Host monotonic clock reliably counts forward except when reset to zero. |
| DTN.A.00012 |
Host provides "host time", an absolute time kept synchronized by the host. Host time is a counter from set epoch known by the DTN Node. |
| DTN.A.00015 |
Host determines if host time is valid and provides a time quality indicator. |
| DTN.A.00017 |
Host will interface to Position, Navigation, and Timing (PNT) services, if necessary, to synchronize clock time. |
- Telemetry Proxy
| DTN.A.02110 |
Host provides a telemetry output application for non-DTN communication channels, which transports CCSDS telemetry packets if applicable. |
| DTN.A.02195 |
Host provides a method to trigger periodic generation of telemetry. |
Appendix C: Acronyms
| Acronym |
Definition |
| AA |
Application Agent |
| ADU |
Application Data Units |
| BP |
Bundle Protocol |
| BPA |
Bundle Protocol Agent |
| BPLib |
Bundle Protocol Library |
| BPNode |
Bundle Protocol Node |
| CBOR |
Concise Binary Object Representation |
| CCSDS |
Consultative Committee for Space Data Systems |
| cFE |
core Flight Executive |
| CFDP |
CCSDS File Delivery Protocol |
| cFS |
code Flight Systems |
| CI |
Core Infrastructure (in the context of BPNode), Command Ingest (in cFS context) |
| CL |
Convergence Layer |
| CLA |
Convergence Layer Adaptor |
| DTN |
Delay/Disruption-Tolerante Network |
| EVS |
Event Services |
| FSW |
Flight Software |
| GSFC |
Goddard Space Flight Center |
| OSAL |
Operating System Abstraction Layer |
| PSP |
Platform Support Package |
| RFC |
Request for Comments |
| SB |
Software Bus |
| SC |
Stored Commands |
| TO |
Telemetry Output |